package auth

import (
	"encoding/json"
	"fmt"
	"net/http"
	"regexp"
	"strings"

	"openSesame/internal/whitelist"
	"openSesame/pkg/config"
	"openSesame/pkg/logger"
)

// Server 认证服务器
type Server struct {
	whitelist *whitelist.Whitelist
	config    *config.AuthConfig
}

// NewServer 创建新的认证服务器
func NewServer(whitelist *whitelist.Whitelist, config *config.AuthConfig) *Server {
	// 确保路径以/开头
	if !strings.HasPrefix(config.Path, "/") {
		config.Path = "/" + config.Path
	}
	return &Server{
		whitelist: whitelist,
		config:    config,
	}
}

// Start 启动认证服务器
func (s *Server) Start() error {
	// 创建新的路由
	mux := http.NewServeMux()

	// 注册认证处理函数
	authPath := s.config.Path
	if authPath == "" {
		authPath = "/auth"
	}
	logger.Infof("Registering auth handler at path: %s", authPath)

	// 创建一个包装的处理函数
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == authPath {
			s.handleAuth(w, r)
		} else {
			http.Error(w, "Invalid Request", http.StatusForbidden)
		}
	})

	// 注册处理函数
	mux.Handle("/", handler)

	// 启动HTTP服务器
	addr := s.config.ListenPort
	fmt.Printf("addr: %v\n", addr)

	logger.Infof("Auth server listening on %s%s", addr, authPath)
	return http.ListenAndServe(addr, mux)
}

// AuthResponse 认证响应结构
type AuthResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
}

// handleAuth 处理认证请求
func (s *Server) handleAuth(w http.ResponseWriter, r *http.Request) {
	// 只允许GET请求
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// 获取客户端IP
	clientIP := r.RemoteAddr
	logger.Infof("New authentication request from %s", clientIP)

	// 从URL参数获取secret
	secret := r.URL.Query().Get("secret")
	if secret == "" {
		http.Error(w, "Invalid Request", http.StatusForbidden)
		return
	}

	// 验证口令
	response := AuthResponse{}
	if regexp.MustCompile(s.config.Secret).MatchString(secret) {
		s.whitelist.Add(clientIP)
		logger.Infof("IP %s successfully authenticated and added to whitelist", clientIP)
		response.Success = true
		response.Message = "Authentication successful"
	} else {
		logger.Warnf("Invalid secret from %s", clientIP)
		response.Success = false
		response.Message = "Invalid secret"
	}

	// 返回JSON响应
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}
